﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace Kokomo.Mirror.PeFormat
{
	[Description("Section Header")]
	public class SectionHeader : PeHeaderStruct
	{
		const int IMAGE_SIZEOF_SHORT_NAME = 8;
		public static readonly int MaxNameLength = IMAGE_SIZEOF_SHORT_NAME;

		public static readonly int StructSize = 0x28;

		public override string ToString()
		{
			return string.Format("{0}: VirtualAddress={1:X8}, Size={2:X8}",
				this.Name,
				this.VirtualAddress,
				this.SizeOfRawData
				);
		}

		//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = IMAGE_SIZEOF_SHORT_NAME)]
		private string _name;
		[SerializedArray(ArrayLengthEncoding.Fixed, IMAGE_SIZEOF_SHORT_NAME)]
		public string Name
		{
			get { return this._name; }
			internal set
			{
				this._name = (value == null) ? null : value.TrimEnd('\0');
			}
		}

		[DisplayName("Virtual size / physical address")]
		[TypeConverter(typeof(HexConverter))]
		public uint PhysicalAddressOrVirtualSize { get; internal set; }

		[DisplayName("Virtual address")]
		[TypeConverter(typeof(HexConverter))]
		public uint VirtualAddress { get; internal set; }

		[DisplayName("Size of raw data")]
		[TypeConverter(typeof(HexConverter))]
		public uint SizeOfRawData { get; internal set; }

		[DisplayName("Pointer to raw data")]
		[TypeConverter(typeof(HexConverter))]
		public uint PointerToRawData { get; internal set; }

		[DisplayName("Pointer to relocations")]
		[TypeConverter(typeof(HexConverter))]
		public uint PointerToRelocations { get; internal set; }

		[DisplayName("Pointer to line numbers")]
		[TypeConverter(typeof(HexConverter))]
		public uint PointerToLinenumbers { get; internal set; }

		[DisplayName("Number of relocations")]
		public ushort NumberOfRelocations { get; internal set; }

		[DisplayName("Number of line numbers")]
		public ushort NumberOfLinenumbers { get; internal set; }

		public SectionCharacteristics Characteristics { get; internal set; }

		public bool Contains(long virtualAddress)
		{
			return ((virtualAddress >= this.VirtualAddress)
				&& (virtualAddress < (long)(this.VirtualAddress + this.SizeOfRawData)));
		}
	}
}
